<?php
class Lucene {
	private $Lucene;
	const MAX_HITS = 50;
	const ENCODING = 'UTF-8';
	private $Path = 'lucene_index';
	const PREFIX_LENGTH = 4; /* lt 4 Performance warn */
	
	protected $_fields = array (array ('key' => 'username', 'type' => 'unStored', 'encoding' => NULL, 'termparam' => NULL ), array ('key' => 'userid', 'type' => 'keyword', 'encoding' => NULL, 'termparam' => NULL ), array ('key' => 'firstname', 'type' => 'unStored', 'encoding' => NULL, 'termparam' => NULL ) );
	
	public function __construct() {
		$this->Path = Zend_Registry::get ( 'config' )->search->index;
		
		Zend_Search_Lucene::setResultSetLimit ( self::MAX_HITS );
		Zend_Search_Lucene_Analysis_Analyzer::setDefault ( new Zend_Search_Lucene_Analysis_Analyzer_Common_Utf8_CaseInsensitive () );
		Zend_Search_Lucene_Search_Query_Wildcard::setMinPrefixLength ( self::PREFIX_LENGTH );
		Zend_Search_Lucene_Search_QueryParser::setDefaultEncoding ( self::ENCODING );
		try {
			$this->Lucene = new Zend_Search_Lucene ( $this->Path, false );
		} catch ( Zend_Search_Lucene_Exception $e ) {
			echo "NO INDEX";
			try {
				$this->Lucene = new Zend_Search_Lucene ( $this->Path, true );
				$this->Lucene->setMaxMergeDocs ( 20 );
			} catch ( Zend_Search_Lucene_Exception $e ) {
				echo "PROBLEM! " . $e->getMessage ();
				return NULL;
			}
		}
	}
	
	function __destruct() {
	
	}
	
	public function ClearAll($value) {
		return mb_strtolower ( self::ClearText ( StripTags ( $value ) ) );
	}
	
	public function ClearText($value) {
		$value = str_replace ( '\'', ' ', $value );
		$value = str_replace ( '"', ' ', $value );
		$value = str_replace ( ',', ' ', $value );
		$value = str_replace ( '.', ' ', $value );
		$value = str_replace ( '\\', ' ', $value );
		return $value;
	}
	
	public function Optimize() {
		$this->Lucene->optimize ();
	}
	
	public function GetInfo() {
		return array ('Index' => $this->Lucene->count (), 'Documents' => $this->Lucene->numDocs () );
	}
	
	public function SearchString($queryString) {
		
		Zend_Search_Lucene_Analysis_Analyzer::setDefault ( new Zend_Search_Lucene_Analysis_Analyzer_Common_Utf8_CaseInsensitive () );
		Zend_Search_Lucene_Search_QueryParser::setDefaultEncoding ( 'UTF-8' );
		Zend_Search_Lucene_Analysis_Analyzer::setDefault ( new Zend_Search_Lucene_Analysis_Analyzer_Common_Utf8 () );
		
		$query = Zend_Search_Lucene_Search_QueryParser::parse ( $queryString );
		$result = $this->Lucene->find ( $query );
		$Array = array ();
		
		foreach ( $result as $hit ) {
			
			//			    $hitArray = array ();
			//			    $dHit = $hit->getDocument();
			//			    foreach ($dHit as $fieldName => $fieldValue)
			//			    {
			//			        $hitArray[$fieldName] = $fieldValue;
			//			    }
			//			    $Array [] = $hitArray;
			

			$Array [] = array ('Text' => $hit->Text, 'Title' => $hit->Title, 'AID' => $hit->AID );
		}
		return $Array;
	}
	
	/*
	    $Doc = array();
         
        $DocField['Type']  = 'Text';
        $DocField['Key']   = 'Text';
        $DocField['Data']  = $Row->Text;
        $Doc[] = $DocField;

         
        $DocField['Type']  = 'Text';
        $DocField['Key']   = 'Title';
        $DocField['Data']  = $Row->Title;
        $Doc[] = $DocField;

        $DocField['Type']  = 'UnIndexed';
        $DocField['Key']   = 'AID';
        $DocField['Data']  = $Row->id;
        $Doc[] = $DocField; 
	*/
	public function AddDocument($Document) {
		
		print_r ( $Document );
		
		$doc = new Zend_Search_Lucene_Document ();
		foreach ( $Document as $Item ) {
			$doc->addField ( call_user_func_array ( 'Zend_Search_Lucene_Field::' . $Item ['Type'], array ($Item ['Key'], $Item ['Data'], 'UTF-8' ) ) );
		}
		
		$this->Lucene->addDocument ( $doc );
		$this->Lucene->commit ();
	
	}
	
	public function deleteByQuery($queryString) {
		Zend_Search_Lucene_Analysis_Analyzer::setDefault ( new Zend_Search_Lucene_Analysis_Analyzer_Common_Utf8_CaseInsensitive () );
		Zend_Search_Lucene_Search_QueryParser::setDefaultEncoding ( 'UTF-8' );
		Zend_Search_Lucene_Analysis_Analyzer::setDefault ( new Zend_Search_Lucene_Analysis_Analyzer_Common_Utf8 () );
		
		$query = Zend_Search_Lucene_Search_QueryParser::parse ( $queryString );
		$result = $this->Lucene->find ( $query );
		$Array = array ();
		foreach ( $result as $hit ) {
			$this->Lucene->delete ( $hit->id );
		}
		
		return $Array;
	}
	
	function clearIndex() {
		
		for($count = 0; $count < $this->Lucene->maxDoc (); $count ++) {
			if ($this->Lucene->isDeleted ( $count )) {
				echo "Document #id is deleted.\n";
			} else {
				$this->Lucene->delete ( $count );
			}
		
		}
	
	}

}

//    Реализация русского стеминга
class Lingua_Stem_Ru {
	var $VERSION = "0.02";
	var $Stem_Caching = 0;
	var $Stem_Cache = array ();
	var $VOWEL = '/аеиоуыэюя/';
	var $PERFECTIVEGROUND = '/((ив|ивши|ившись|ыв|ывши|ывшись)|((?<=[ая])(в|вши|вшись)))$/';
	var $REFLEXIVE = '/(с[яь])$/';
	var $ADJECTIVE = '/(ее|ие|ые|ое|ими|ыми|ей|ий|ый|ой|ем|им|ым|ом|его|ого|еых|ую|юю|ая|яя|ою|ею)$/';
	var $PARTICIPLE = '/((ивш|ывш|ующ)|((?<=[ая])(ем|нн|вш|ющ|щ)))$/';
	var $VERB = '/((ила|ыла|ена|ейте|уйте|ите|или|ыли|ей|уй|ил|ыл|им|ым|ены|ить|ыть|ишь|ую|ю)|((?<=[ая])(ла|на|ете|йте|ли|й|л|ем|н|ло|но|ет|ют|ны|ть|ешь|нно)))$/';
	var $NOUN = '/(а|ев|ов|ие|ье|е|иями|ями|ами|еи|ии|и|ией|ей|ой|ий|й|и|ы|ь|ию|ью|ю|ия|ья|я)$/';
	var $RVRE = '/^(.*?[аеиоуыэюя])(.*)$/';
	var $DERIVATIONAL = '/[^аеиоуыэюя][аеиоуыэюя]+[^аеиоуыэюя]+[аеиоуыэюя].*(?<=о)сть?$/';
	
	function s(&$s, $re, $to) {
		$orig = $s;
		$s = preg_replace ( $re, $to, $s );
		return $orig !== $s;
	}
	
	function m($s, $re) {
		return preg_match ( $re, $s );
	}
	
	function stem_word($word) {
		$word = mb_convert_case ( $word, MB_CASE_LOWER, "UTF-8" );
		$word = strtr ( $word, array ('ё' => 'е' ) );
		# Check against cache of stemmed words
		

		$stem = $word;
		do {
			if (! preg_match ( $this->RVRE, $word, $p ))
				break;
			$start = $p [1];
			$RV = $p [2];
			if (! $RV)
				break;
			
		# Step 1
			if (! $this->s ( $RV, $this->PERFECTIVEGROUND, '' )) {
				$this->s ( $RV, $this->REFLEXIVE, '' );
				
				if ($this->s ( $RV, $this->ADJECTIVE, '' )) {
					$this->s ( $RV, $this->PARTICIPLE, '' );
				} else {
					if (! $this->s ( $RV, $this->VERB, '' ))
						$this->s ( $RV, $this->NOUN, '' );
				}
			}
			
			# Step 2
			$this->s ( $RV, '/и$/', '' );
			
			# Step 3
			if ($this->m ( $RV, $this->DERIVATIONAL ))
				$this->s ( $RV, '/ость?$/', '' );
			
		# Step 4
			if (! $this->s ( $RV, '/ь$/', '' )) {
				$this->s ( $RV, '/ейше?/', '' );
				$this->s ( $RV, '/нн$/', 'н' );
			}
			
			$stem = $start . $RV;
		} while ( false );
		return $stem;
	}

}

function ArrayUTFtoCP($Array) {
	foreach ( $Array as $key => $value )
		foreach ( $value as $inkey => $invalue )
			$Array [$key] [$inkey] = iconv ( 'UTF-8', 'CP1251', $Array [$key] [$inkey] );
	
	return $Array;
}

function StripTags($value) {
	$Filter = new Zend_Filter_StripTags ();
	return $Filter->filter ( $value );
}
